﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.Expression.Encoder;
using Microsoft.Expression.Encoder.Profiles;
using System.Data.Linq;
using System.IO;
using System.Net;

namespace UCCLIGHT2.Encoder.Util
{
    public class EncoderUtil
    {
        string base_path = "";
        string upload_path = @"UPload\";
        string thumbnail_temp_path = @"UPload\Thumbnails\";
        string encoded_path = @"Encoded\";

        bool isEncoding = false;

        public bool IsEncoding
        {
            get { return isEncoding; }
            set { isEncoding = value; }
        }

        double progress = 0;

        public double Progress
        {
            get { return progress; }
            set { progress = value; }
        }

        public EncoderUtil(string base_file_path)
        {
            base_path = base_file_path;
        }

        public void DoEncode(int idx, string filename, int e_option)
        {
            try
            {
                isEncoding = true;

                Job job = new Job();
                job.OutputDirectory = base_path + encoded_path;
                job.CreateSubfolder = false;
                job.EncodeProgress += new EventHandler<EncodeProgressEventArgs>(job_EncodeProgress);
                job.EncodeCompleted += new EventHandler<EncodeCompletedEventArgs>(job_EncodeCompleted);

                MediaItem mi = new MediaItem(base_path + upload_path + filename);
                mi.VideoResizeMode = VideoResizeMode.Letterbox;

                AdvancedVC1VideoProfile videoprofile = new AdvancedVC1VideoProfile();

                switch (e_option)
                {
                    case 0: //low
                        videoprofile.Bitrate = mi.SourceVideoProfile.Bitrate;
                        videoprofile.FrameRate = mi.SourceVideoProfile.FrameRate / 2;
                        videoprofile.Size = new Size(mi.SourceVideoProfile.Size.Width / 4, mi.SourceVideoProfile.Size.Height / 4);
                        break;
                    case 1: //mid
                        videoprofile.Bitrate = mi.SourceVideoProfile.Bitrate;
                        videoprofile.FrameRate = mi.SourceVideoProfile.FrameRate / 1.5;
                        videoprofile.Size = new Size(mi.SourceVideoProfile.Size.Width / 2, mi.SourceVideoProfile.Size.Height / 2);
                        break;
                    case 2: //high
                        videoprofile.Bitrate = mi.SourceVideoProfile.Bitrate;
                        videoprofile.FrameRate = mi.SourceVideoProfile.FrameRate;
                        videoprofile.Size = mi.SourceVideoProfile.Size;
                        break;
                    case 3: //smooth
                        videoprofile.Streams.RemoveAt(0);
                        videoprofile.Streams.Add(new VariableConstrainedBitrate(1450, 1600), mi.SourceVideoProfile.Size);
                        videoprofile.Streams.Add(new VariableConstrainedBitrate(1050, 1600), mi.SourceVideoProfile.Size);
                        videoprofile.Streams.Add(new VariableConstrainedBitrate(600, 1600), mi.SourceVideoProfile.Size);

                        // Use smooth streaming with automatically sized streams.
                        videoprofile.SmoothStreaming = true;
                        videoprofile.Streams.AutoSize = true;
                        break;
                }

                mi.OutputFormat.VideoProfile = videoprofile;

                job.MediaItems.Add(mi);
                job.Encode();

                //Update Database
                UpdateStatus(idx, 1);

                File.Delete(base_path + upload_path + filename);
            }
            catch
            {
                //Update Database
                UpdateStatus(idx, 2);

                isEncoding = false;
            }
        }

        /// <summary>
        /// Update Encoding Status
        /// </summary>
        /// <param name="idx">database index</param>
        /// <param name="status">Status 0-not encoded, 1-encoded succesful, 2 encoding error</param>
        private static void UpdateStatus(int idx, int status)
        {
            HttpWebRequest req;
            Uri target = new Uri("http://localhost:17627/Default.aspx");
            req = (HttpWebRequest)HttpWebRequest.Create(target);
        }

        void job_EncodeProgress(object sender, EncodeProgressEventArgs e)
        {
            progress = e.Progress;
        }

        void job_EncodeCompleted(object sender, EncodeCompletedEventArgs e)
        {
            IsEncoding = false;
        }

        /// <summary>
        /// Get Thumbnails List
        /// </summary>
        /// <param name="name">uploaded file name</param>
        /// <returns>thumbnails path list. : xml</returns>
        public XElement GetThumbnails(string name)
        {
            string mediapath = base_path + upload_path + name;

            MediaItem media = new MediaItem(mediapath);

            int total = (int)(media.FileDuration.TotalSeconds);

            XElement xml = new XElement("Thumbnails");

            Bitmap img = media.MainMediaFile.GetThumbnail(TimeSpan.FromSeconds(3), media.VideoSize);
            string full_path = base_path + thumbnail_temp_path + name + "_1.png";
            img.Save(full_path, ImageFormat.Png);
            xml.Add(new XElement("Thumbnail", full_path));

            img = media.MainMediaFile.GetThumbnail(TimeSpan.FromSeconds(total / 5), media.VideoSize);
            full_path = base_path + thumbnail_temp_path + name + "_2.png";
            img.Save(full_path, ImageFormat.Png);
            xml.Add(new XElement("Thumbnail", full_path));
            
            img = media.MainMediaFile.GetThumbnail(TimeSpan.FromSeconds((total / 5) * 2), media.VideoSize);
            full_path = base_path + thumbnail_temp_path + name + "_3.png";
            img.Save(full_path, ImageFormat.Png);
            xml.Add(new XElement("Thumbnail", full_path));
            
            img = media.MainMediaFile.GetThumbnail(TimeSpan.FromSeconds((total / 5) * 3), media.VideoSize);
            full_path = base_path + thumbnail_temp_path + name + "_4.png";
            img.Save(full_path, ImageFormat.Png);
            xml.Add(new XElement("Thumbnail", full_path));
            
            img = media.MainMediaFile.GetThumbnail(TimeSpan.FromSeconds((total / 5) * 4), media.VideoSize);
            full_path = base_path + thumbnail_temp_path + name + "_5.png";
            img.Save(full_path, ImageFormat.Png);
            xml.Add(new XElement("Thumbnail", full_path));

            return xml;
        }
    }
}
